package net.gdface.facedb;

import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
import org.apache.commons.configuration2.interpol.InterpolatorSpecification;
import org.apache.commons.configuration2.io.FileHandler;

import com.gitee.l0km.com4j.base.ConfigUtils;
import com.google.common.base.Function;

import static org.apache.commons.configuration2.interpol.ConfigurationInterpolator.*;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Properties;

public class PropertyUtil {

	private static final ConfigurationInterpolator interpolator;
	private PropertyUtil() {
	}
	static
	{
		InterpolatorSpecification spec =
				new InterpolatorSpecification.Builder()
				.withPrefixLookups(getDefaultPrefixLookups())
				.withDefaultLookups(getDefaultPrefixLookups().values())
				.create();
		interpolator = fromSpecification(spec);
	}
	/**
	 * 解析指定的字符串值,替换变量
	 * @param value
	 * @return 替代占位符后的字符串
	 */
	public static String resolve(String value){
		return (String) interpolator.interpolate(value);
	}
	public static Properties resolve(Properties props){
		if(null != props){
			for(String name:props.stringPropertyNames()){
				String resolved = resolve(props.getProperty(name));
				props.setProperty(name, resolved);
			}
		}
		return props;
	}
	
	/**
	 * 基于user.home，加载相对路径propPath指定的properties文件
	 * @param propPath
	 * @return 所有变量都解析过占位符的 Properties 实例
	 */
	public static Properties loadPropertiesInUserHome(String propPath){
		Properties props = ConfigUtils.loadPropertiesInUserHome(propPath);
		return new InterpolatorProperties(resolve(props));
	}
	/**
	 * 加载路径propPath指定的properties文件
	 * @param propPath
	 * @return 所有变量都解析过占位符的 Properties 实例
	 */
	public static Properties loadProperties(File propPath){
		try {
			Properties props = ConfigUtils.loadProperties(propPath);
			return normalize(props);
		} catch ( IOException e) {
			throw new RuntimeException(e);
		}
	}
	public static Properties normalize(Properties props){
		return new InterpolatorProperties(resolve(props));
		
	}
	
	public static PropertiesConfiguration asConfiguration(String basePath,String propFile){
		PropertiesConfiguration config = new PropertiesConfiguration();
		if(null != propFile){
			FileHandler handler = new FileHandler(config);
			handler.setBasePath(basePath);
			handler.setFileName(propFile);
			try {
				handler.load();
			} catch (ConfigurationException e) {
				throw new RuntimeException(e);
			}
		}
        return config;
	}
	public static PropertiesConfiguration asConfiguration(Properties properties){
		if(null == properties){
			properties = new Properties();
		}
		PropertiesConfiguration config = new PropertiesConfiguration();
		StringWriter stringWriter = new StringWriter();
		properties.list(new PrintWriter(stringWriter));
		try {
			config.read(new StringReader(stringWriter.toString()));
		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (ConfigurationException e) {
			throw new RuntimeException(e);
		}
		return config;
	}
	public static final Function<String,String> FUN_RESOLVE= new Function<String,String>(){

		@Override
		public String apply(String input) {
			return resolve(input);
		}};
		
	@SuppressWarnings("serial")
	private static class InterpolatorProperties extends Properties{

		public InterpolatorProperties(Properties copy) {
			super();
			if(copy != null){
				for(String name:copy.stringPropertyNames()){
					setProperty(name, copy.getProperty(name));
				}
			}
		}

		@Override
		public String getProperty(String key, String defaultValue) {
			return super.getProperty(key, resolve(defaultValue));
		}
		
	}
}
